<template>
  <a-table :data-source="dataSource" :columns="columns" class="search-table" row-key="name">
    <div
      slot="filterDropdown"
      slot-scope="{ setSelectedKeys, selectedKeys, confirm, clearFilters, column }"
      style="padding: 8px"
    >
      <a-input
        v-ant-ref="(c) => (searchInput = c)"
        :placeholder="`请输入 ${column.dataIndex}搜索`"
        :value="selectedKeys[0]"
        style="width: 188px; margin-bottom: 8px; display: block"
        @change="(e) => setSelectedKeys(e.target.value ? [e.target.value] : [])"
        @pressEnter="() => handleSearch(selectedKeys, confirm, column.dataIndex)"
      />
      <a-button
        type="primary"
        icon="search"
        size="small"
        style="width: 90px; margin-right: 8px"
        @click="() => handleSearch(selectedKeys, confirm, column.dataIndex)"
      >
        搜索
      </a-button>
      <a-button size="small" style="width: 90px" @click="() => handleReset(clearFilters)"> 重置 </a-button>
    </div>
    <a-icon
      slot="filterIcon"
      slot-scope="filtered"
      type="search"
      :style="{ color: filtered ? '#108ee9' : undefined }"
    />
    <a-icon
      slot="outputFilterIcon"
      slot-scope="filtered"
      type="filter"
      theme="filled"
      :style="{ color: filtered ? '#108ee9' : undefined }"
    />
    <template slot="customRender" slot-scope="text, record, index, column">
      <span v-if="searchText && searchedColumn === column.dataIndex">
        <template
          v-for="(fragment, i) in text.toString().split(new RegExp(`(?<=${searchText})|(?=${searchText})`, 'i'))"
        >
          <mark v-if="fragment.toLowerCase() === searchText.toLowerCase()" :key="i" class="highlight">{{
            fragment
          }}</mark>
          <template v-else>{{ fragment }}</template>
        </template>
      </span>
      <template v-else>
        <a-tooltip :title="text">
          <template #content>
            <div>{{ text }}</div>
          </template>
          <span>{{ text }}</span>
        </a-tooltip>
      </template>
    </template>
    <template slot="editName" slot-scope="text, record">
      <editable-cell :text="text" @change="onCellChange(record.key, 'dName', $event)" :output="output" />
    </template>
  </a-table>
</template>

<script>
import EditableCell from './EditableCell'

const OUTPUT_ITEM_MAP = {
  TOTAL: '总分',
  SCORE: '单变量小分',
  LABEL: '标签',
  RANGE: '数值区间',
}
export default {
  name: 'SearchTable',
  props: {
    requestParams: {
      type: Object,
      default: () => {},
    },
    dataSource: {
      type: Array,
      default: () => [],
    },
    output: {
      type: Boolean,
      default: false,
    },
  },
  components: {
    EditableCell,
  },
  data() {
    return {
      searchText: '',
      searchInput: null,
      searchedColumn: '',
      columns: this.output
        ? [
            {
              title: '变量名',
              dataIndex: 'name',
              key: 'name',
              ellipsis: true,
              scopedSlots: {
                filterDropdown: 'filterDropdown',
                filterIcon: 'filterIcon',
                customRender: 'customRender',
              },
              onFilter: (value, record) => record.name.toString().toLowerCase().includes(value.toLowerCase()),
              onFilterDropdownVisibleChange: (visible) => {
                if (visible) {
                  setTimeout(() => {
                    this.searchInput.focus()
                  }, 0)
                }
              },
            },
            {
              title: '变量数据类型',
              dataIndex: 'datatype',
              key: 'datatype',
            },
            {
              title: '输出项',
              dataIndex: 'outputItem',
              key: 'outputItem',
              filters: Object.keys(OUTPUT_ITEM_MAP).map((key) => ({
                text: OUTPUT_ITEM_MAP[key],
                value: key,
              })),
              scopedSlots: {
                filterIcon: 'outputFilterIcon',
              },
              onFilter: (value, record) => record.outputItem === value,
              customRender: (text, record) => {
                return OUTPUT_ITEM_MAP[record.outputItem]
              },
            },
            {
              title: '输出变量名',
              dataIndex: 'dName',
              key: 'dName',
              scopedSlots: {
                customRender: 'editName',
              },
            },
          ]
        : [
            {
              title: '字段名',
              dataIndex: 'name',
              key: 'name',
              ellipsis: true,
              scopedSlots: {
                filterDropdown: 'filterDropdown',
                filterIcon: 'filterIcon',
                customRender: 'customRender',
              },
              onFilter: (value, record) => record.name.toString().toLowerCase().includes(value.toLowerCase()),
              onFilterDropdownVisibleChange: (visible) => {
                if (visible) {
                  setTimeout(() => {
                    this.searchInput.focus()
                  }, 0)
                }
              },
            },
            {
              title: '显示名',
              dataIndex: 'dName',
              key: 'dName',
              ellipsis: true,
              scopedSlots: {
                customRender: 'editName',
              },
            },
            {
              title: '变量数据类型',
              dataIndex: 'datatype',
              key: 'datatype',
            },
            {
              title: '描述',
              dataIndex: 'description',
              key: 'description',
            },
          ],
    }
  },
  methods: {
    handleSearch(selectedKeys, confirm, dataIndex) {
      confirm()
      this.searchText = selectedKeys[0]
      this.searchedColumn = dataIndex
    },

    handleReset(clearFilters) {
      clearFilters()
      this.searchText = ''
    },
    onCellChange(key, dataIndex, value) {
      const dataSource = [...this.dataSource]
      const target = dataSource.find((item) => item.key === key)
      if (target) {
        target[dataIndex] = value
        this.$emit('update:dataSource', dataSource)
      }
    },
  },
}
</script>
<style scoped lang="less">
/* 确保搜索图标颜色为主题色 */
.ant-table-thead > tr > th .anticon-filter, .ant-table-thead > tr > th .ant-table-filter-icon {
  color: @primary-color !important;
}
</style>
